﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Collections;

namespace ModuleSettings
{
    public static class SettingsUtil
    {
        #region SettingsProperty

        /// <summary>
        /// indicate whether the given settings property contains the a attribute with the given data type
        /// </summary>
        /// <param name="property">settings property which contains the info of a settings entity (name, type and default value)</param>
        /// <param name="type">a type of a attribute for the settings property</param>
        /// <returns>true, when the given settings property contains a attribute with the given data type</returns>
        public static bool AttributeExists(SettingsProperty property, Type type)
        {
            foreach (DictionaryEntry d in property.Attributes)
            {
                Attribute a = (Attribute)d.Value;
                if (a.GetType() == type)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// indicate whether a SettingsProperty is a application settings
        /// </summary>
        /// <param name="property">settings property which contains the info of a settings entity (name, type and default value)</param>
        /// <returns>true, when the given settings property is a application settings</returns>
        public static bool IsApplicationScopeSettings(SettingsProperty property)
        {
            return AttributeExists(property, typeof(ApplicationScopedSettingAttribute));
        }

        /// <summary>
        /// indicate whether a SettingsProperty is a roaming settings
        /// </summary>
        /// <param name="property">settings property which contains the info of a settings entity (name, type and default value)</param>
        /// <returns>true, when the given settings property is a roaming settings</returns>
        public static bool IsRoamingSettings(SettingsProperty property)
        {
            return AttributeExists(property, typeof(SettingsManageabilityAttribute));
        }

        /// <summary>
        /// indicate whether a SettingsProperty is a user settings
        /// </summary>
        /// <param name="property">settings property which contains the info of a settings entity (name, type and default value)</param>
        /// <returns>true, when the given settings property is a user settings</returns>
        public static bool IsUserScopeSettings(SettingsProperty property)
        {
            return AttributeExists(property, typeof(UserScopedSettingAttribute));
        }

        public static void RegisterPropertyProvider(ApplicationSettingsBase clazz, string propName, SettingsProvider provider)
        {
            if (clazz == null) throw new ArgumentNullException("The given Settings instance is null");
            if (provider == null) throw new ArgumentNullException("The given instance of the type SettingsProvider is null");
            if (string.IsNullOrEmpty(propName)) throw new ArgumentNullException("The property name of a settings is null");

            foreach (SettingsProperty sp in clazz.Properties)
            {
                if (sp.Name.Equals(propName))
                    sp.Provider = provider;
            }

            throw new ArgumentException("The given property name does not exist in the given Settings class");
        }

        #endregion SettingsProperty

        #region SettingsClass

        public static void RegisterClassProvider(ApplicationSettingsBase clazz, SettingsProvider provider)
        {
            if (clazz == null) throw new ArgumentNullException("The given Settings instance is null");
            if (provider == null) throw new ArgumentNullException("The given instance of the type SettingsProvider is null");

            clazz.Providers.Clear();
            clazz.Providers.Add(provider);
            foreach (SettingsProperty sp in clazz.Properties)
            {
                sp.Provider = provider;
            }
        }

        

        #endregion SettingsClass

        public static void Reset(this ApplicationSettingsBase settings, params string[] propNames)
        {
            IEnumerator list = settings.Providers.GetEnumerator();
            bool hasProvider = list.MoveNext();
            ModuleSettingsProviderBase provider = hasProvider ? list.Current as ModuleSettingsProviderBase : null;
            if (provider != null)
                provider.Reset(propNames);
            
        }
    }
}
